Revert "Add ostree-shutdown.service: hide /sysroot and make /etc read-only"
authorEtienne Champetier <e.champetier@ateme.com>
Wed, 3 Sep 2025 18:22:39 +0000 (14:22 -0400)
committerEtienne Champetier <e.champetier@ateme.com>
Thu, 4 Sep 2025 19:04:39 +0000 (15:04 -0400)
Instead of adding a shutdown service, we rework how we create the mounts.
After the 2 previous commits, sysroot.mount umount works, and
systemd-shutdown will take care of remounting etc.mount read-only and
calling sync() as needed.

This reverts commit d0c454c23637dceda6d7395dd2141b564e3efa47.

Makefile-boot.am
src/boot/ostree-shutdown.service [deleted file]
src/libostree/ostree-impl-system-generator.c
src/switchroot/ostree-remount.c

index e26c18161bc0483bba0ad78c50574afc178f7959..7b7cb892e25aacb512a898ad32ae350acc73ae96 100644 (file)
@@ -38,7 +38,6 @@ endif
 if BUILDOPT_SYSTEMD
 systemdsystemunit_DATA = src/boot/ostree-prepare-root.service \
        src/boot/ostree-remount.service \
-       src/boot/ostree-shutdown.service \
        src/boot/ostree-boot-complete.service \
        src/boot/ostree-finalize-staged.service \
        src/boot/ostree-finalize-staged-hold.service \
@@ -70,7 +69,6 @@ EXTRA_DIST += src/boot/dracut/module-setup.sh \
        src/boot/ostree-boot-complete.service \
        src/boot/ostree-prepare-root.service \
        src/boot/ostree-remount.service \
-       src/boot/ostree-shutdown.service \
        src/boot/ostree-finalize-staged.service \
        src/boot/ostree-finalize-staged-hold.service \
        src/boot/ostree-state-overlay@.service \
diff --git a/src/boot/ostree-shutdown.service b/src/boot/ostree-shutdown.service
deleted file mode 100644 (file)
index 24919ec..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.0+
-
-[Unit]
-Description=OSTree Shutdown
-Documentation=man:ostree(1)
-DefaultDependencies=no
-# Only enabled via generator, but for good measure
-ConditionKernelCommandLine=ostree
-# Run after core mounts
-RequiresMountsFor=/etc /sysroot
-# However, we want to only shut down after `/var` has been umounted.
-# Since this runs via ExecStop, this Before= is actually After= at shutdown
-Before=var.mount
-Conflicts=umount.target
-Before=umount.target
-
-[Service]
-Type=oneshot
-RemainAfterExit=yes
-ExecStop=/usr/lib/ostree/ostree-remount --shutdown
-
-# No [Install] section - we're only enabled via generator
index 65f07fd5dec0d2791586d76145f44965fb222e7d..f0116251c5d89b445dc781da2da2436f08953f21 100644 (file)
@@ -108,10 +108,6 @@ require_internal_units (const char *normal_dir, const char *early_dir, const cha
                  "local-fs.target.requires/ostree-remount.service")
       < 0)
     return glnx_throw_errno_prefix (error, "symlinkat");
-  if (symlinkat (SYSTEM_DATA_UNIT_PATH "/ostree-shutdown.service", normal_dir_dfd,
-                 "local-fs.target.wants/ostree-shutdown.service")
-      < 0)
-    return glnx_throw_errno_prefix (error, "symlinkat");
 
   if (!glnx_shutil_mkdir_p_at (normal_dir_dfd, "multi-user.target.wants", 0755, cancellable, error))
     return FALSE;
index b1c829ea7e65fc6d6c857a5685ce76cbe578eb05..f0a4b3d925bee22aaab6216346c5d37f7fcaac3b 100644 (file)
 #include "ostree-mount-util.h"
 #include "otcore.h"
 
-static gboolean opt_shutdown;
-
-static GOptionEntry options[] = { { "shutdown", 'S', 0, G_OPTION_ARG_NONE, &opt_shutdown,
-                                    "Perform shutdown unmounting", NULL },
-                                  { NULL } };
-
 static void
 do_remount (const char *target, bool writable)
 {
@@ -139,61 +133,10 @@ relabel_dir_for_upper (const char *upper_path, const char *real_path, gboolean i
 #endif
 }
 
-// ostree-prepare-root sets things up so that /sysroot points to the "physical" (real) root in the
-// initramfs, and then with composefs `/` is an overlay+EROFS that holds references to content in
-// that physical filesystem.
-//
-// In a typical mutable system where the OS is in a mutable `/` (or `/usr), systemd explicitly
-// skips unmounting both `/` and `/usr`. It will remount them read-only though - and that's
-// the semantic we want to match here.
-static void
-do_shutdown (void)
-{
-  const char *sysroot = "/sysroot";
-  if (mount (sysroot, sysroot, NULL, MS_REMOUNT | MS_SILENT | MS_RDONLY, NULL) < 0)
-    {
-      // Hopefully at this point nothing has any write references, but if they
-      // do we still want to continue.
-      perror ("Remounting /sysroot read-only");
-    }
-  // And fully detach it from the mountns because otherwise systemd thinks
-  // it can be unmounted, but it can't - it's required by `/` (and in a
-  // composefs setup `/etc`) and possibly `/var`. Again, we only really
-  // care that it got mounted read-only and hence outstanding data flushed.
-  // A better fix in the future would be to teach systemd to honor `-.mount`
-  // having a `Requires=sysroot.mount` meaning we can't unmount the latter.
-  if (umount2 (sysroot, MNT_DETACH) < 0)
-    err (EXIT_FAILURE, "umount(/sysroot)");
-
-  // And finally: /etc
-  // NOTE! This one is intentionally last in that we want to try to make
-  // this read-only, but if it fails, systemd-shutdown will have another
-  // attempt after a process killing spree. If anything happens to be
-  // holding a writable fd at this point, conceptually it would have
-  // created race conditions vs ostree-finalize-staged.service, and so
-  // having this service fail will be a signal that those things need
-  // to be fixed.
-  do_remount ("/etc", false);
-  // Don't add anything else after this.
-}
-
 int
 main (int argc, char *argv[])
 {
   g_autoptr (GError) error = NULL;
-  g_autoptr (GOptionContext) context = g_option_context_new ("");
-  g_option_context_add_main_entries (context, options, NULL);
-  if (!g_option_context_parse (context, &argc, &argv, &error))
-    errx (EXIT_FAILURE, "Error parsing options: %s", error->message);
-
-  // Handle the shutdown option
-  if (opt_shutdown)
-    {
-      do_shutdown ();
-      return 0;
-    }
-  // Otherwise fall through to the default startup
-
   g_autoptr (GVariant) ostree_run_metadata_v = NULL;
   {
     glnx_autofd int fd = open (OTCORE_RUN_BOOTED, O_RDONLY | O_CLOEXEC);